﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "NdbObjectMemoryModelPropertyAccessor.h"
#include "NdbClassSchemaLibraryOfCode.h"
#include "NdbTypeTraits.h"
#include "NdbObjectMemoryModelNode.h"
#include "NdbArchiveBlockHeader.h"
#include "IIOStream.h"
#include "ISerializationBehavior.h"
#include "NdbCustomUpgraderPropertyUtils.h"
#include "IIODevice.h"
#include "IDbObjectArchive.h"

namespace gcmp
{
    template<class T>
    class NdbCustomUpgraderPropertyGetterBase
    {
    public:
        NdbCustomUpgraderPropertyGetterBase(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : m_pObjectMemoryModelNode(pObjectMemoryModelNode) {}

        bool HasProperty(const std::wstring& name)
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            return NdbObjectMemoryModelPropertyAccessor<T>::HasProperty(pObjectMemoryModelGroupNode, name);
        }
    protected:
        const NdbObjectMemoryModelNode *m_pObjectMemoryModelNode;
    };

    template<class T, class Enable = void>
    class NdbCustomUpgraderPropertyGetter : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode)
        {
            STATIC_ASSERT_FALSE("Please check NdbTypeTraits.h for supported property type.");
        }

        bool GetPropertyValue(const std::wstring& propertyName, T &value)
        {
            STATIC_ASSERT_FALSE("Please check NdbTypeTraits.h for supported property type.");
            return false;
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter<T, typename std::enable_if<property_is_value_type<T>::value || property_is_elementId_type<T>::value>::type> : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, T &value)
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            bool result = false;
            value = *NdbObjectMemoryModelPropertyAccessor<T>::GetProperty(pObjectMemoryModelGroupNode, propertyName, result);
            return result;
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter<T, typename std::enable_if<property_is_wstring_type<T>::value>::type> : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, T &value)
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");

            const std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& childNodes = pObjectMemoryModelGroupNode->GetSubNodes();
            auto ite = std::find_if(childNodes.begin(), childNodes.end(), [&propertyName](const OwnerPtr<NdbObjectMemoryModelNode>& opNode) -> bool {
                return (opNode->GetName() == propertyName);
            });
            DBG_WARN_AND_RETURN_FALSE_UNLESS(ite != childNodes.end(), L"没有找到属性:" + propertyName, L"GMEP", L"2017/01/22");
            DBG_WARN_AND_RETURN_FALSE_UNLESS((*ite)->IsLeaf(), L"属性:" + propertyName + L"的数据类型是复合类型（非叶子节点）,不建议直接取用。请参见NdbPropertySchemaType.h中属性数据类型的定义", L"GMEP", L"2017/01/22");
            const NdbObjectMemoryModelLeafNode* pLeafNode = thread_safe_quick_cast<NdbObjectMemoryModelLeafNode>((*ite).get());
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pLeafNode, L"Only support set property of leaf node", L"GMEP", L"2020/10/31");
            if (pLeafNode->GetDataSize() > 0)
            {
                value = StringUtil::ToWString(std::string((char*)pLeafNode->GetData(), pLeafNode->GetDataSize()));
            }
            else
            {
                value = std::wstring();
            }
            return true;
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter<T, typename std::enable_if<property_is_object_schematic_type<T>::value>::type> : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, T& value) const
        {
            NdbObject *pNewObject = thread_safe_quick_cast<NdbObject>(&value);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNewObject, L"参数输入错误", L"GMEP", L"2018-01-31");

            return NdbCustomUpgraderPropertyUtils::CopyNdbObject(m_pObjectMemoryModelNode, propertyName, pNewObject);
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter<T, typename std::enable_if<property_is_object_cloneable_type<T>::value>::type> : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, T& value) const
        {
            NdbObject *pNewObject = thread_safe_quick_cast<NdbObject>(&value);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNewObject, L"参数输入错误", L"GMEP", L"2018-01-31");

            return NdbCustomUpgraderPropertyUtils::CopyNdbObject(m_pObjectMemoryModelNode, propertyName, pNewObject);
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter<gcmp::OwnerPtr<T>, typename std::enable_if<property_is_object_schematic_owner_ptr_type<gcmp::OwnerPtr<T>>::value>::type> : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, gcmp::OwnerPtr<T>& value) const
        {
            OwnerPtr<NdbObject> opObjectOwned = NdbCustomUpgraderPropertyUtils::GetOwnedNdbObject(m_pObjectMemoryModelNode, propertyName);
            if (opObjectOwned.get() != nullptr)
            {
                (OwnerPtr<NdbObject>&)value = TransferOwnership(opObjectOwned);
                return true;
            }
            return false;
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter<gcmp::OwnerPtr<T>, typename std::enable_if<property_is_object_cloneable_owner_ptr_type<gcmp::OwnerPtr<T>>::value>::type> : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, gcmp::OwnerPtr<T>& value) const
        {
            OwnerPtr<NdbObject> opObjectOwned = NdbCustomUpgraderPropertyUtils::GetOwnedNdbObject(m_pObjectMemoryModelNode, propertyName);
            if (opObjectOwned.get() != nullptr)
            {
                (OwnerPtr<NdbObject>&)value = TransferOwnership(opObjectOwned);
                return true;
            }
            return false;
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter < gcmp::OwnerPtr<T>, typename std::enable_if <property_is_idbobject_owner_ptr_type<gcmp::OwnerPtr<T>>::value
        && !property_is_object_schematic_owner_ptr_type<gcmp::OwnerPtr<T>>::value> ::type > : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}
 
        bool GetPropertyValue(const std::wstring& propertyName, gcmp::OwnerPtr<T>& value) const
        {
            OwnerPtr<IDbObject> opObjectOwned = NdbCustomUpgraderPropertyUtils::GetOwnedIDbObject(m_pObjectMemoryModelNode, propertyName);
            if (opObjectOwned)
            {
                (OwnerPtr<IDbObject>&)value = TransferOwnership(opObjectOwned);
                return true;
            }
            return false;
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter<NdbVector<T>, typename std::enable_if<property_is_vector_type<NdbVector<T>>::value>::type> : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, NdbVector<T>& value) const
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            const std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& childNodes = pObjectMemoryModelGroupNode->GetSubNodes();
            auto iter = std::find_if(childNodes.begin(), childNodes.end(), [&propertyName](const OwnerPtr<NdbObjectMemoryModelNode>& opNode) -> bool {
                DBG_WARN_AND_RETURN_FALSE_UNLESS(opNode.get(), L"opNode.get() is nullptr", L"GMEP", L"2018-01-31");
                return (opNode->GetName() == propertyName);
            });
            if (iter == childNodes.end())
            {
                return false;
            }

            NdbUpgradeManager* pNdbUpgradeManager = NdbUpgradeManager::GetInstance();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbUpgradeManager, L"pNdbUpgradeManager为空", L"GMEP", L"2018-01-31");
            const NdbClassSchemaLibraryOfFile* pNdbClassSchemaLibraryOfFile = pNdbUpgradeManager->GetClassScheamLibraryOfFile();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbClassSchemaLibraryOfFile, L"pNdbClassSchemaLibraryOfFile为空", L"GMEP", L"2018-01-31");

            value.NdbExtractObjectFromMemory(const_cast<NdbObjectMemoryModelNode*>((*iter).get()), pNdbClassSchemaLibraryOfFile->GetMajorVersion());
            return true;
        }
    };

    template<class T>
    class NdbCustomUpgraderPropertyGetter<NdbSet<T>, typename std::enable_if<property_is_set_type<NdbSet<T>>::value>::type> : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, NdbSet<T>& value) const
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            const std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& childNodes = pObjectMemoryModelGroupNode->GetSubNodes();
            auto iter = std::find_if(childNodes.begin(), childNodes.end(), [&propertyName](const OwnerPtr<NdbObjectMemoryModelNode>& opNode) -> bool {
                DBG_WARN_AND_RETURN_FALSE_UNLESS(opNode.get(), L"opNode.get() is nullptr", L"GMEP", L"2018-01-31");
                return (opNode->GetName() == propertyName);
            });
            if (iter == childNodes.end())
            {
                return false;
            }

            NdbUpgradeManager* pNdbUpgradeManager = NdbUpgradeManager::GetInstance();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbUpgradeManager, L"pNdbUpgradeManager为空", L"GMEP", L"2018-01-31");
            const NdbClassSchemaLibraryOfFile* pNdbClassSchemaLibraryOfFile = pNdbUpgradeManager->GetClassScheamLibraryOfFile();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbClassSchemaLibraryOfFile, L"pNdbClassSchemaLibraryOfFile为空", L"GMEP", L"2018-01-31");

            value.NdbExtractObjectFromMemory(const_cast<NdbObjectMemoryModelNode*>((*iter).get()), pNdbClassSchemaLibraryOfFile->GetMajorVersion());
            return true;
        }
    };

    template<class Key, class T, class KeyCompare>
    class NdbCustomUpgraderPropertyGetter<NdbMap<Key, T, KeyCompare>, typename std::enable_if<property_is_map_type<NdbMap<Key, T, KeyCompare>>::value>::type>
        : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, NdbMap<Key, T, KeyCompare>& value) const
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            const std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& childNodes = pObjectMemoryModelGroupNode->GetSubNodes();
            auto iter = std::find_if(childNodes.begin(), childNodes.end(), [&propertyName](const OwnerPtr<NdbObjectMemoryModelNode>& opNode) -> bool {
                DBG_WARN_AND_RETURN_FALSE_UNLESS(opNode.get(), L"opNode.get() is nullptr", L"GMEP", L"2018-01-31");
                return (opNode->GetName() == propertyName);
            });
            if (iter == childNodes.end())
            {
                return false;
            }

            NdbUpgradeManager* pNdbUpgradeManager = NdbUpgradeManager::GetInstance();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbUpgradeManager, L"pNdbUpgradeManager为空", L"GMEP", L"2018-01-31");
            const NdbClassSchemaLibraryOfFile* pNdbClassSchemaLibraryOfFile = pNdbUpgradeManager->GetClassScheamLibraryOfFile();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbClassSchemaLibraryOfFile, L"pNdbClassSchemaLibraryOfFile为空", L"GMEP", L"2018-01-31");

            value.NdbExtractObjectFromMemory(const_cast<NdbObjectMemoryModelNode*>((*iter).get()), pNdbClassSchemaLibraryOfFile->GetMajorVersion());
            return true;
        }
    };

    template<class Key, class T, class Hash>
    class NdbCustomUpgraderPropertyGetter<NdbUnorderedMap<Key, T, Hash>, typename std::enable_if<property_is_unordermap_type<NdbUnorderedMap<Key, T, Hash>>::value>::type>
        : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, NdbUnorderedMap<Key, T, Hash>& value) const
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            const std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& childNodes = pObjectMemoryModelGroupNode->GetSubNodes();
            auto iter = std::find_if(childNodes.begin(), childNodes.end(), [&propertyName](const OwnerPtr<NdbObjectMemoryModelNode>& opNode) -> bool {
                DBG_WARN_AND_RETURN_FALSE_UNLESS(opNode.get(), L"opNode.get() is nullptr", L"GMEP", L"2018-01-31");
                return (opNode->GetName() == propertyName);
            });
            if (iter == childNodes.end())
            {
                return false;
            }

            NdbUpgradeManager* pNdbUpgradeManager = NdbUpgradeManager::GetInstance();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbUpgradeManager, L"pNdbUpgradeManager为空", L"GMEP", L"2018-01-31");
            const NdbClassSchemaLibraryOfFile* pNdbClassSchemaLibraryOfFile = pNdbUpgradeManager->GetClassScheamLibraryOfFile();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbClassSchemaLibraryOfFile, L"pNdbClassSchemaLibraryOfFile为空", L"GMEP", L"2018-01-31");

            value.NdbExtractObjectFromMemory(const_cast<NdbObjectMemoryModelNode*>((*iter).get()), pNdbClassSchemaLibraryOfFile->GetMajorVersion());
            return true;
        }
    };

    template<class Key, class T>
    class NdbCustomUpgraderMapPropertyGetter : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderMapPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, gcmp::NdbMap<Key, T>& value) const
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            const std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& childNodes = pObjectMemoryModelGroupNode->GetSubNodes();
            auto iter = std::find_if(childNodes.begin(), childNodes.end(), [&propertyName](const OwnerPtr<NdbObjectMemoryModelNode>& opNode) -> bool {
                DBG_WARN_AND_RETURN_FALSE_UNLESS(opNode.get(), L"opNode.get() is nullptr", L"GMEP", L"2018-01-31");
                return (opNode->GetName() == propertyName);
            });
            if (iter == childNodes.end())
            {
                return false;
            }

            NdbUpgradeManager* pNdbUpgradeManager = NdbUpgradeManager::GetInstance();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbUpgradeManager, L"pNdbUpgradeManager为空", L"GMEP", L"2018-01-31");
            const NdbClassSchemaLibraryOfFile* pNdbClassSchemaLibraryOfFile = pNdbUpgradeManager->GetClassScheamLibraryOfFile();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbClassSchemaLibraryOfFile, L"pNdbClassSchemaLibraryOfFile为空", L"GMEP", L"2018-01-31");

            value.NdbExtractObjectFromMemory(const_cast<NdbObjectMemoryModelNode*>((*iter).get()), pNdbClassSchemaLibraryOfFile->GetMajorVersion());
            return true;
        }
    };

    template<class Key, class T>
    class NdbCustomUpgraderUnorderedMapPropertyGetter : public NdbCustomUpgraderPropertyGetterBase<T>
    {
    public:
        NdbCustomUpgraderUnorderedMapPropertyGetter(const NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertyGetterBase(pObjectMemoryModelNode) {}

        bool GetPropertyValue(const std::wstring& propertyName, gcmp::NdbUnorderedMap<Key, T>& value) const
        {
            const NdbObjectMemoryModelGroupNode *pObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            const std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& childNodes = pObjectMemoryModelGroupNode->GetSubNodes();
            auto iter = std::find_if(childNodes.begin(), childNodes.end(), [&propertyName](const OwnerPtr<NdbObjectMemoryModelNode>& opNode) -> bool {
                DBG_WARN_AND_RETURN_FALSE_UNLESS(opNode.get(), L"opNode.get() is nullptr", L"GMEP", L"2018-01-31");
                return (opNode->GetName() == propertyName);
            });
            if (iter == childNodes.end())
            {
                return false;
            }

            NdbUpgradeManager* pNdbUpgradeManager = NdbUpgradeManager::GetInstance();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbUpgradeManager, L"pNdbUpgradeManager为空", L"GMEP", L"2018-01-31");
            const NdbClassSchemaLibraryOfFile* pNdbClassSchemaLibraryOfFile = pNdbUpgradeManager->GetClassScheamLibraryOfFile();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNdbClassSchemaLibraryOfFile, L"pNdbClassSchemaLibraryOfFile为空", L"GMEP", L"2018-01-31");

            value.NdbExtractObjectFromMemory(const_cast<NdbObjectMemoryModelNode*>((*iter).get()), pNdbClassSchemaLibraryOfFile->GetMajorVersion());
            return true;
        }
    };

    template <typename T>
    inline UInt64 SerializeValueAsProperty(const T& value, const NdbPropertySchema &propertySchema, OwnerPtr<IDbObjectArchive>& archive)
    {
        NdbArchiveBlockHeader dataHeader;
        IntBaseType intBaseType = NdbPropertySchemaTypeTrait<T>::IntBaseType;
        IntOrFloatType intOrFloatType = NdbPropertySchemaTypeTrait<T>::IntOrFloatType;
        Int32 attributes = NdbArchiveBlockHeader::CombineAttributes(propertySchema.GetPropertySchemaType(), intOrFloatType, intBaseType);
        dataHeader.SetAttributes(attributes);

        UInt64 propertySize = propertySchema.GetPropertySize();
        dataHeader.SetBodyLength(propertySize);
        Int32 headerLen = dataHeader.Serialize(archive->GetIOStream());
        archive->GetIOStream().Write(&value, propertySize);

        return propertySize;
    }

    inline UInt64 SerializeWStringAsProperty(const std::wstring& value, const NdbPropertySchema& propSchema, OwnerPtr<IDbObjectArchive>& archive)
    {
        UInt64 len = 0;

        const UInt64 strLen = archive->GetIOStream().WriteString(value);
        if (strLen == -1)
        {
            return -1;
        }
        len += strLen;

        return len;
    }

    template <typename T>
    inline UInt64 SerializeOwnerPtrAsProperty(const T& value, const NdbPropertySchema &propertySchema, OwnerPtr<IDbObjectArchive>& archive)
    {
        IIOStream & ioStream = archive->GetIOStream();

        NdbArchiveBlockHeader ownedObjDataHeader;
        ownedObjDataHeader.SetAttributes(static_cast<Int32>(NdbPropertySchemaType::Invalid));
        Int32 ownedHeaderLen = ownedObjDataHeader.Serialize(ioStream);
        UInt64 ownedBodyLen = 0;

        if (nullptr != value.get())
        {
            const NdbObjectCloneable* pObjectCloneable = thread_safe_quick_cast<NdbObjectCloneable>(value.get());
            if (pObjectCloneable)
            {
                ownedBodyLen += SerializeOwnerPtrMetaData(value, ioStream);
                ownedObjDataHeader.SetAttributes(static_cast<Int32>(NdbPropertySchemaType::CloneableObject));
                const Int64 posBefore = ioStream.GetDevice()->Pos();
                const UInt64 objectLen = pObjectCloneable->NdbSerialize(*archive.get());
                if (objectLen == -1)
                {
                    return -1;
                }
                ownedBodyLen += objectLen;

                const Int64 posAfter = ioStream.GetDevice()->Pos();
                if ((posAfter - posBefore) != (Int64)objectLen)
                {
                    std::wostringstream woss;
                    woss << L"序列化属性时写入到文件的大小和属性对象的大小不一致，写入到文件的大小是：" << (posAfter - posBefore) << L"，而属性对象的大小是：" << objectLen;
                    DBG_WARN(woss.str(), L"GMEP", L"2017/01/24");
                }
            }
            else if (const NdbObjectContainer* pObjectContainer = thread_safe_quick_cast<NdbObjectContainer>(value.get()))
            {
                ownedBodyLen += SerializeOwnerPtrMetaData(value, ioStream);
                //理论上ownerptr不会存容器指针，此段代码可以去掉
                ownedObjDataHeader.SetAttributes(static_cast<Int32>(pObjectContainer->GetSchemaType()));
                const Int64 posBefore = ioStream.GetDevice()->Pos();
                const UInt64 objectLen = pObjectContainer->NdbSerialize(*archive.get(), NdbPropertyUtils::PropertyBehaveAsDeclaration);
                if (objectLen == -1)
                {
                    return -1;
                }
                ownedBodyLen += objectLen;

                const Int64 posAfter = ioStream.GetDevice()->Pos();
                if ((posAfter - posBefore) != (Int64)objectLen)
                {
                    std::wostringstream woss;
                    woss << L"序列化属性时写入到文件的大小和属性对象的大小不一致，写入到文件的大小是：" << (posAfter - posBefore) << L"，而属性对象的大小是：" << objectLen;
                    DBG_WARN(woss.str(), L"GMEP", L"2017/01/24");
                }
            }
            else if (const NdbObjectSchematic * pNDbObject = thread_safe_quick_cast<NdbObjectSchematic>(value.get()))
            {
                const NdbObject * pOwnedObject = thread_safe_quick_cast<NdbObject>(value.get());
                ownedBodyLen += NdbCustomUpgraderPropertyUtils::SerializeNdbObjectBody(archive, pOwnedObject);
                ownedObjDataHeader.SetAttributes(static_cast<Int32>(NdbPropertySchemaType::SchematicObject));
            }
            else if (const IDbObject * pIDbObject = thread_safe_quick_cast<IDbObject>(value.get()))
            {
                const Guid guild = pIDbObject->GetClassGuid();
                ioStream << guild;
                ownedBodyLen += sizeof(Guid);
                ownedObjDataHeader.SetAttributes(static_cast<Int32>(NdbPropertySchemaType::IDbObject));

                std::vector<char> buffer;
                ISerializationBehavior * pSerializationBehavior = pIDbObject->GetSerializationBehavior();
                pSerializationBehavior->Serialize(buffer);
                if (buffer.empty())
                {
                    return 0;
                }

                Int32 bufferLen = SafeTypeCast<Int32>(buffer.size());
                ioStream << bufferLen;
                ownedBodyLen += sizeof(bufferLen);
                const UInt64 posBefore = ioStream.GetDevice()->Pos();
                ioStream.Write(buffer.data(), bufferLen);
                ownedBodyLen += bufferLen;

                const UInt64 posAfter = ioStream.GetDevice()->Pos();
                if ((posAfter - posBefore) != buffer.size())
                {
                    std::wostringstream woss;
                    woss << L"序列化属性时写入到文件的大小和属性对象的大小不一致，写入到文件的大小是：" << (posAfter - posBefore) << L"，而属性对象的大小是：" << bufferLen;
                    DBG_WARN(woss.str(), L"GMEP", L"2017/01/24");
                }
            }
            else
            {
                const NdbObject * pOwnedObject = thread_safe_quick_cast<NdbObject>(value.get());
                DBG_WARN_AND_RETURN_UNLESS(pOwnedObject, -1, L"pOwnerObject is nullptr", L"GMEP", L"2017/01/24");
                const NdbClassSchema* pPropClassSchema = pOwnedObject->GetClassSchema();
                DBG_WARN_AND_RETURN_UNLESS(pPropClassSchema, -1, L"pPropClassSchema is nullptr", L"GMEP", L"2017/01/24");
                ownedObjDataHeader.SetAttributes(static_cast<Int32>(NdbPropertySchemaType::SchematicObject));

                IIODevice* pIODevice = ioStream.GetDevice();
                DBG_WARN_AND_RETURN_UNLESS(pIODevice, -1, L"pIODevice is nullptr", L"GMEP", L"2017/01/24");
                const Int64 posBefore = ioStream.GetDevice()->Pos();
                const UInt64 objectLen = NdbCustomUpgraderPropertyUtils::GetNdbObjectLength(archive, pOwnedObject, pPropClassSchema);
                if (objectLen == -1)
                {
                    return -1;
                }
                ownedBodyLen += objectLen;

                const Int64 posAfter = ioStream.GetDevice()->Pos();
                if ((posAfter - posBefore) != (Int64)objectLen)
                {
                    std::wostringstream woss;
                    woss << L"序列化属性时写入到文件的大小和属性对象的大小不一致，写入到文件的大小是：" << (posAfter - posBefore) << L"，而属性对象的大小是：" << objectLen;
                    DBG_WARN(woss.str(), L"GMEP", L"2017/01/24");
                }
            }
        }
        // 向后移动文件指针，回填parent object的头部
        IIODevice* pIODevice = ioStream.GetDevice();
        DBG_WARN_AND_RETURN_UNLESS(pIODevice, -1, L"pIODevice is nullptr", L"GMEP", L"2017/01/24");
        pIODevice->Seek(-SafeTypeCast<Int64>(ownedHeaderLen + ownedBodyLen), std::ios_base::cur);
        ownedObjDataHeader.SetBodyLength(ownedBodyLen);
        ownedObjDataHeader.Serialize(ioStream);
        // 向前恢复文件指针
        ioStream.GetDevice()->Seek((Int64)(ownedBodyLen), std::ios_base::cur);

        return ownedHeaderLen + ownedBodyLen;
    }

    template <typename T>
    inline UInt64 SerializeOwnerPtrMetaData(const T& value, IIOStream& ioStream)
    {
        const NdbObject * pOwnedObject = thread_safe_quick_cast<NdbObject>(value.get());
        DBG_WARN_AND_RETURN_UNLESS(pOwnedObject, -1, L"pOwnerObject is nullptr", L"GMEP", L"2017/01/24");
        const NdbClassSchema* pPropClassSchema = pOwnedObject->GetClassSchema();
        DBG_WARN_AND_RETURN_UNLESS(pPropClassSchema, -1, L"pPropClassSchema is nullptr", L"GMEP", L"2017/01/24");

        UInt64 ownerPtrMetaDataLen = 0;
        // 记录classSchema
        const std::wstring& classIdStr = pPropClassSchema->GetClassId().AsWString();
        ownerPtrMetaDataLen += ioStream.WriteString(classIdStr);

        // 类version
        const UInt32 ownedClassVersion = pPropClassSchema->GetVersion();
        ioStream << ownedClassVersion;
        ownerPtrMetaDataLen += sizeof(UInt32);

        return ownerPtrMetaDataLen;
    }

    template <typename T>
    inline UInt64 SerializeSchemaObjectAsProperty(const T& value, const NdbPropertySchema &propertySchema, OwnerPtr<IDbObjectArchive>& archive)
    {
        UInt64 len = 0;

        const NdbObject *pPropObject = &value;
        DBG_WARN_AND_RETURN_UNLESS(pPropObject, -1, L"pPropObject is nullptr", L"GMEP", L"2017/01/24");

        const NdbClassSchema* pPropClassSchema = pPropObject->GetClassSchema();
        DBG_WARN_AND_RETURN_UNLESS(pPropClassSchema, -1, L"pPropClassSchema is nullptr", L"GMEP", L"2017/01/24");

        const ClassId & propClassId = pPropClassSchema->GetClassId();
        // 记录classSchema的索引
        //archive.GetIOStream() << pPropClassSchema->GetIndex();
        //len += sizeof(UInt32);

        // 类版本
        const UInt32 propClassVersion = pPropClassSchema->GetVersion();
        //archive.GetIOStream() << propClassVersion;
        //len += sizeof(UInt32);

        const UInt64 propObjectLen = NdbCustomUpgraderPropertyUtils::GetNdbObjectLength(archive, pPropObject, pPropClassSchema);
        if (propObjectLen == -1)
        {
            return -1;
        }
        len += propObjectLen;

        return len;
    }

    template <typename T>
    inline UInt64 SerializeNativePointerAsProperty(const T& value, const NdbPropertySchema &propertySchema, OwnerPtr<IDbObjectArchive>& archive)
    {
        // 指针没有必要序列化
        return 0;
    }

    template <typename T>
    inline UInt64 SerializeCloneableObjectAsProperty(const T& value, const NdbPropertySchema &propertySchema, OwnerPtr<IDbObjectArchive>& archive)
    {
        UInt64 len = 0;
        DBG_WARN_AND_RETURN_UNLESS(archive.get(), -1, L"archive.get() is nullptr", L"GMEP", L"2017/01/24");

        const NdbObject *pPropObject = &value;
        DBG_WARN_AND_RETURN_UNLESS(pPropObject, -1, L"pPropObject is nullptr", L"GMEP", L"2017/01/24");

        const NdbClassSchema* pPropClassSchema = pPropObject->GetClassSchema();
        DBG_WARN_AND_RETURN_UNLESS(pPropClassSchema, -1, L"pPropClassSchema is nullptr", L"GMEP", L"2017/01/24");

        // 记录classSchema
        const std::wstring& classIdStr = pPropClassSchema->GetClassId();
        len += archive->GetIOStream().WriteString(classIdStr);

        UInt32 version = pPropClassSchema->GetVersion();
        archive->GetIOStream() << version;
        len += sizeof(UInt32);

        const Int32 objectLen = pPropObject->NdbSerialize(*archive.get());
        if (objectLen == -1)
        {
            return -1;
        }
        len += objectLen;

        return len;
    }

    template <typename T>
    inline UInt64 SerializeContainerAsProperty(const T& value, const NdbPropertySchema &propertySchema, OwnerPtr<IDbObjectArchive>& archive)
    {
        const NdbObjectContainer *pPropObject = &value;
        DBG_WARN_AND_RETURN_UNLESS(pPropObject, -1, L"pPropObject is nullptr", L"GMEP", L"2017/01/24");
        const UInt64 objectLen = pPropObject->NdbSerialize(*archive.get(), NdbPropertyUtils::PropertyBehaveAsDeclaration);
        if (objectLen == -1)
        {
            return -1;
        }
        return objectLen;
    }

    class NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetterBase(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : m_pObjectMemoryModelNode(pObjectMemoryModelNode) {}

        ~NdbCustomUpgraderPropertySetterBase() {}

    protected:
        bool GetPropertySchema(const std::wstring& propertyName, NdbPropertySchema& propSchema) const
        {
            NdbObjectMemoryModelGroupNode *pNewObjectMemoryModelGroupNode = thread_safe_quick_cast<NdbObjectMemoryModelGroupNode>(m_pObjectMemoryModelNode);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pNewObjectMemoryModelGroupNode, L"获取属性的节点必须是组节点", L"GMEP", L"2018-01-31");
            ClassId classId = pNewObjectMemoryModelGroupNode->GetClassId();
            const NdbClassSchema* pClassSchema = NdbClassSchemaLibraryOfCode::GetInstance()->GetSchemaByClassId(classId);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pClassSchema, classId.AsWString() + L"的ClassSchema不存在", L"GMEP", L"2018-01-31");
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pClassSchema->GetPropertySchema(propertyName, propSchema), propertyName + L"属性不存在", L"GMEP", L"2018-01-31");
            return true;
        }

        NdbObjectMemoryModelNode *m_pObjectMemoryModelNode;
    };

    template<typename T, class Enable = void>
    class NdbCustomUpgraderPropertySetter : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const T& value)
        {
            STATIC_ASSERT_FALSE("Please check NdbTypeTraits.h for supported property type.");
            return false;
        }
    };

    template<typename T>
    class NdbCustomUpgraderPropertySetter<T, typename std::enable_if<property_is_value_type<T>::value || property_is_elementId_type<T>::value>::type> : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const T& value)
        {
            NdbPropertySchema propSchema;
            bool getPropSchemaRes = GetPropertySchema(propertyName, propSchema);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(getPropSchemaRes, L"该对象没有" + propertyName + L"属性", L"GMEP", L"2018/02/03");
            NdbPropertySchemaType schemaType = propSchema.GetPropertySchemaType();

            NdbCustomUpgraderPropertyUtils ndbCustomUpgraderPropertyUtils;
            OwnerPtr<IDbObjectArchive> opObjectArchive = ndbCustomUpgraderPropertyUtils.CreateNdbObjectArchive();
            UInt64 propLen = SerializeValueAsProperty(value, propSchema, opObjectArchive);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(propLen > 0, L"序列化属性" + propertyName + L"失败", L"GMEP", L"2018/02/03");

            return NdbCustomUpgraderPropertyUtils::CreateAndReplacePropertyNode(propSchema, *opObjectArchive->GetIOStream().GetDevice(), m_pObjectMemoryModelNode);
        }
    };

    template<typename T>
    class NdbCustomUpgraderPropertySetter<T, typename std::enable_if<property_is_wstring_type<T>::value>::type> : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const T& value)
        {
            NdbPropertySchema propSchema;
            bool getPropSchemaRes = GetPropertySchema(propertyName, propSchema);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(getPropSchemaRes, L"该对象没有" + propertyName + L"属性", L"GMEP", L"2018/02/03");
            NdbPropertySchemaType schemaType = propSchema.GetPropertySchemaType();

            NdbCustomUpgraderPropertyUtils ndbCustomUpgraderPropertyUtils;
            OwnerPtr<IDbObjectArchive> opObjectArchive = ndbCustomUpgraderPropertyUtils.CreateNdbObjectArchive();
            UInt64 propLen = SerializeWStringAsProperty(value, propSchema, opObjectArchive);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(propLen > 0, L"序列化属性" + propertyName + L"失败", L"GMEP", L"2018/02/03");

            return NdbCustomUpgraderPropertyUtils::CreateAndReplacePropertyNode(propSchema, *opObjectArchive->GetIOStream().GetDevice(), m_pObjectMemoryModelNode);
        }
    };

    template<typename T>
    class NdbCustomUpgraderPropertySetter<T, typename std::enable_if<property_is_object_schematic_type<T>::value>::type> : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const T& value)
        {
            NdbPropertySchema propSchema;
            bool getPropSchemaRes = GetPropertySchema(propertyName, propSchema);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(getPropSchemaRes, L"该对象没有" + propertyName + L"属性", L"GMEP", L"2018/02/03");
            NdbPropertySchemaType schemaType = propSchema.GetPropertySchemaType();

            NdbCustomUpgraderPropertyUtils ndbCustomUpgraderPropertyUtils;
            OwnerPtr<IDbObjectArchive> opObjectArchive = ndbCustomUpgraderPropertyUtils.CreateNdbObjectArchive();
            UInt64 propLen = SerializeSchemaObjectAsProperty(value, propSchema, opObjectArchive);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(propLen != (UInt64)-1, L"序列化属性" + propertyName + L"失败", L"GMEP", L"2018/02/03");

            return NdbCustomUpgraderPropertyUtils::CreateAndReplacePropertyNode(propSchema, *opObjectArchive->GetIOStream().GetDevice(), m_pObjectMemoryModelNode);
        }
    };

    template<typename T>
    class NdbCustomUpgraderPropertySetter<T, typename std::enable_if<property_is_object_cloneable_type<T>::value>::type> : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const T& value)
        {
            NdbPropertySchema propSchema;
            bool getPropSchemaRes = GetPropertySchema(propertyName, propSchema);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(getPropSchemaRes, L"该对象没有" + propertyName + L"属性", L"GMEP", L"2018/02/03");
            NdbPropertySchemaType schemaType = propSchema.GetPropertySchemaType();

            NdbCustomUpgraderPropertyUtils ndbCustomUpgraderPropertyUtils;
            OwnerPtr<IDbObjectArchive> opObjectArchive = ndbCustomUpgraderPropertyUtils.CreateNdbObjectArchive();
            UInt64 propLen = SerializeCloneableObjectAsProperty(value, propSchema, opObjectArchive);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(propLen > 0, L"序列化属性" + propertyName + L"失败", L"GMEP", L"2018/02/03");

            return NdbCustomUpgraderPropertyUtils::CreateAndReplacePropertyNode(propSchema, *opObjectArchive->GetIOStream().GetDevice(), m_pObjectMemoryModelNode);
        }
    };

    template<typename T>
    class NdbCustomUpgraderPropertySetter<gcmp::OwnerPtr<T>, typename std::enable_if<property_is_object_schematic_owner_ptr_type<gcmp::OwnerPtr<T>>::value>::type> : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const gcmp::OwnerPtr<T> & value)
        {
            NdbPropertySchema propSchema;
            bool getPropSchemaRes = GetPropertySchema(propertyName, propSchema);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(getPropSchemaRes, L"该对象没有" + propertyName + L"属性", L"GMEP", L"2018/02/03");
            NdbPropertySchemaType schemaType = propSchema.GetPropertySchemaType();

            NdbCustomUpgraderPropertyUtils ndbCustomUpgraderPropertyUtils;
            OwnerPtr<IDbObjectArchive> opObjectArchive = ndbCustomUpgraderPropertyUtils.CreateNdbObjectArchive();
            UInt64 propLen = SerializeOwnerPtrAsProperty(value, propSchema, opObjectArchive);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(propLen > 0, L"序列化属性" + propertyName + L"失败", L"GMEP", L"2018/02/03");

            return NdbCustomUpgraderPropertyUtils::CreateAndReplacePropertyNode(propSchema, *opObjectArchive->GetIOStream().GetDevice(), m_pObjectMemoryModelNode);
        }
    };

    template<typename T>
    class NdbCustomUpgraderPropertySetter<gcmp::OwnerPtr<T>, typename std::enable_if<property_is_object_cloneable_owner_ptr_type<gcmp::OwnerPtr<T>>::value>::type> : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const gcmp::OwnerPtr<T> & value)
        {
            NdbPropertySchema propSchema;
            bool getPropSchemaRes = GetPropertySchema(propertyName, propSchema);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(getPropSchemaRes, L"该对象没有" + propertyName + L"属性", L"GMEP", L"2018/02/03");
            NdbPropertySchemaType schemaType = propSchema.GetPropertySchemaType();

            NdbCustomUpgraderPropertyUtils ndbCustomUpgraderPropertyUtils;
            OwnerPtr<IDbObjectArchive> opObjectArchive = ndbCustomUpgraderPropertyUtils.CreateNdbObjectArchive();
            UInt64    propLen = SerializeOwnerPtrAsProperty(value, propSchema, opObjectArchive);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(propLen > 0, L"序列化属性" + propertyName + L"失败", L"GMEP", L"2018/02/03");

            return NdbCustomUpgraderPropertyUtils::CreateAndReplacePropertyNode(propSchema, *opObjectArchive->GetIOStream().GetDevice(), m_pObjectMemoryModelNode);
        }

    };
    template<typename T>
    class NdbCustomUpgraderPropertySetter<gcmp::OwnerPtr<T>, typename std::enable_if<property_is_idbobject_owner_ptr_type<gcmp::OwnerPtr<T>>::value
        && !property_is_object_schematic_owner_ptr_type<gcmp::OwnerPtr<T>>::value>::type> : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const gcmp::OwnerPtr<T> & value)
        {
            NdbPropertySchema propSchema;
            bool getPropSchemaRes = GetPropertySchema(propertyName, propSchema);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(getPropSchemaRes, L"该对象没有" + propertyName + L"属性", L"GMEP", L"2018/02/03");
            NdbPropertySchemaType schemaType = propSchema.GetPropertySchemaType();

            NdbCustomUpgraderPropertyUtils ndbCustomUpgraderPropertyUtils;
            OwnerPtr<IDbObjectArchive> opObjectArchive = ndbCustomUpgraderPropertyUtils.CreateNdbObjectArchive();
            UInt64 propLen = SerializeOwnerPtrAsProperty(value, propSchema, opObjectArchive);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(propLen > 0, L"序列化属性" + propertyName + L"失败", L"GMEP", L"2018/02/03");

            return NdbCustomUpgraderPropertyUtils::CreateAndReplacePropertyNode(propSchema, *opObjectArchive->GetIOStream().GetDevice(), m_pObjectMemoryModelNode);
        }
    };

    template<typename T>
    class NdbCustomUpgraderPropertySetter<T, typename std::enable_if<
        property_is_vector_type<T>::value ||
        property_is_set_type<T>::value ||
        property_is_map_type<T>::value ||
        property_is_unordermap_type<T>::value
    >::type> : public NdbCustomUpgraderPropertySetterBase
    {
    public:
        NdbCustomUpgraderPropertySetter(NdbObjectMemoryModelNode *pObjectMemoryModelNode) : NdbCustomUpgraderPropertySetterBase(pObjectMemoryModelNode) {}
    public:
        bool SetPropertyValue(const std::wstring& propertyName, const T& value)
        {
            NdbPropertySchema propSchema;
            bool getPropSchemaRes = GetPropertySchema(propertyName, propSchema);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(getPropSchemaRes, L"该对象没有" + propertyName + L"属性", L"GMEP", L"2018/02/03");
            NdbPropertySchemaType schemaType = propSchema.GetPropertySchemaType();

            NdbCustomUpgraderPropertyUtils ndbCustomUpgraderPropertyUtils;
            OwnerPtr<IDbObjectArchive> opObjectArchive = ndbCustomUpgraderPropertyUtils.CreateNdbObjectArchive();
            UInt64 propLen = SerializeContainerAsProperty(value, propSchema, opObjectArchive);
            DBG_WARN_AND_RETURN_FALSE_UNLESS(propLen > 0, L"序列化属性" + propertyName + L"失败", L"GMEP", L"2018/02/03");

            return NdbCustomUpgraderPropertyUtils::CreateAndReplacePropertyNode(propSchema, *opObjectArchive->GetIOStream().GetDevice(), m_pObjectMemoryModelNode);
        }
    };
}